
package me.zhengjie.service.impl;

import me.zhengjie.domain.AppWork;
import me.zhengjie.domain.AppWorkConfig;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.modules.system.service.RoleService;
import me.zhengjie.modules.system.service.UserService;
import me.zhengjie.modules.system.service.dto.RoleSmallDto;
import me.zhengjie.modules.system.service.dto.UserDto;
import me.zhengjie.repository.AppWorkRepository;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.repository.AppWorkConfigRepository;
import me.zhengjie.service.AppWorkConfigService;
import me.zhengjie.service.dto.AppWorkConfigDto;
import me.zhengjie.service.dto.AppWorkConfigQueryCriteria;
import me.zhengjie.service.mapstruct.AppWorkConfigMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author IQW
* @date 2022-07-13
**/
@Service
@RequiredArgsConstructor
public class AppWorkConfigServiceImpl implements AppWorkConfigService {

    private final AppWorkConfigRepository appWorkConfigRepository;
    private final AppWorkConfigMapper appWorkConfigMapper;

    private final UserService userService;
    private final RoleService roleService;
    private final AppWorkRepository appWorkRepository;


    @Override
    public Map<String,Object> queryAll(AppWorkConfigQueryCriteria criteria, Pageable pageable){


        //获取最小权限
        Integer currentLevel =  Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList()));
        System.out.println("min level:"+currentLevel);
        if(currentLevel<=2){
            //管理员查看所有
        }else{
            //查看当前责任区
            Long userId = SecurityUtils.getCurrentUserId();
            UserDto user = userService.findById(userId);
            criteria.setAreaId(user.getAreaId());
        }

        Page<AppWorkConfig> page = appWorkConfigRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(appWorkConfigMapper::toDto));
    }

    @Override
    public List<AppWorkConfigDto> queryAll(AppWorkConfigQueryCriteria criteria){
        return appWorkConfigMapper.toDto(appWorkConfigRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    public List<AppWorkConfig> queryAllOrg(AppWorkConfigQueryCriteria criteria){
        return appWorkConfigRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
    }

    @Override
    @Transactional
    public Boolean setWorkConfigExp() {
        appWorkConfigRepository.setWorkConfigExp(DateUtils.getNowTimestamp());
        return true;
    }

    @Override
    public Boolean actWorkConfig(Integer configId){

        System.out.println("-------进入任务执行--------");
        System.out.println("-------configId="+configId);
        AppWorkConfigQueryCriteria criteria = new AppWorkConfigQueryCriteria();
        criteria.setStatus(1);
        criteria.setStartTime(DateUtils.getNowTimestamp());
        criteria.setEndTime(DateUtils.getNowTimestamp());
        if(configId > 0){
            criteria.setConfigId(configId);
        }
        List<AppWorkConfig> list  = this.queryAllOrg(criteria);
        System.out.println("-------list.size="+list.size());
        List<User> users = userService.findAll();
        for (AppWorkConfig item : list){

            //每num次danwei时间，生成一次任务
            String danwei = item.getDanwei();
            Integer num = item.getNum();
            if(num == 0) {
                num =1;
            }

            //如果执行时间和今天相同，则跳过
            Timestamp _nowDayStart = DateUtils.getDayStartTimestamp();
            long nowDayStart = _nowDayStart.getTime();

            //1天2周3月4年
            long add = 0;
            if(!StringUtils.isNull(danwei)){
                switch (danwei){
                    case "2": add = (long)num*7*1000*3600*24;nowDayStart -= add;break;
                    case "3": add = (long)num*30*1000*3600*24;nowDayStart -= add; break;
                    case "4": add = (long)num*365*1000*3600*24;nowDayStart -= add; break;
                    default: add = (long)num*1000*3600*24;nowDayStart -= add; break;
                }
            }
            boolean isRun = true; //是否可以执行

            if(null !=item.getZxDate() ){
                if(item.getType() == 2) {
                    System.out.println("now：跳过一次性任务");
                    continue;
                }
                if(_nowDayStart.getTime() == item.getZxDate().getTime()) {
                    System.out.println("now：跳过今日,已经执行过");
                    continue;
                }else if(nowDayStart == item.getZxDate().getTime()){
                    System.out.println("时间相等，可以执行");
                    isRun = true;
                }else{
                    System.out.println("时间不等,不可以执行");
                    isRun = false;
                }
            }
            if(!isRun){
                System.out.println("isRun：执行跳过");
                continue;
            }

            //循环所有用户，批量生成任务
            for (User user :users){

                //跳过管理员
                if(user.getType() == 1){
                    continue;
                }
                //检测责任区
                if(null == user.getAreaId() || null == item.getToAreaId() ||
                        user.getAreaId().intValue() != item.getToAreaId().intValue()){
                    continue;
                }
                //to_type 1全部，2林长，3护林员，4个人
                if(item.getToType() == 1){
                    //不用处理
                }else if(item.getToType() == 2){
                    int role = userService.findRoleByUser(user);
                    if(role != 1){
                        //不是林长
                        continue;
                    }
                }else if(item.getToType() == 3){
                    int role = userService.findRoleByUser(user);
                    if(role == 1){
                        //不是护林员
                        continue;
                    }
                }else if(item.getToType() == 4){
                    if(StringUtils.isEmpty(item.getUids())){
                        continue;   //全部跳过
                    }
                    String orgStr = ","+item.getUids()+",";
                    if(!orgStr.contains(","+user.getId()+",")){
                        continue;
                    }
                }

                //生成任务
                AppWork tmp = new AppWork();
                tmp.setConfigId(item.getConfigId());
                tmp.setUserId(user.getId().intValue());
                tmp.setTitle(item.getTitle());
                tmp.setAreaId(item.getAreaId());
                String address = user.getWorkArea();
                double lon = user.getLon();
                double lat = user.getLat();
                if(null != item.getLat() && item.getLat()!=0L && null!= item.getLon() && item.getLon() != 0L){
                    lon = item.getLon();
                    lat = item.getLat();
                    address = item.getAddress();
                }
                tmp.setLat(lat);
                tmp.setLon(lon);
                tmp.setAddress(address);
                tmp.setNote(item.getNote());
                tmp.setLabel(item.getLabel());
                tmp.setJjcd(item.getJjcd());
                tmp.setStatus(0);
                tmp.setStartTime(DateUtils.getDayStartTimestamp());
                if(item.getType() == 2){
                    //一次性任务，取任务的结束日期
                    tmp.setEndTime(item.getEndTime());
                }else{
                    tmp.setEndTime(DateUtils.getDayEndPlusTimestamp(add));
                }
                tmp.setCreateTime(DateUtils.getNowTimestamp());
                appWorkRepository.save(tmp);
            }
            //更新当前任务标记
            item.setZxDate(DateUtils.getDayStartTimestamp());
            appWorkConfigRepository.save(item);
            System.out.println("-------更新完当前任务，ID="+item.getConfigId());

        }

        return true;
    }

    @Override
    @Transactional
    public AppWorkConfigDto findById(Integer configId) {
        AppWorkConfig appWorkConfig = appWorkConfigRepository.findById(configId).orElseGet(AppWorkConfig::new);
        ValidationUtil.isNull(appWorkConfig.getConfigId(),"AppWorkConfig","configId",configId);
        return appWorkConfigMapper.toDto(appWorkConfig);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppWorkConfigDto create(AppWorkConfig resources) {

        //type类型：1周期，2临时一次
        if(null == resources.getNum() || resources.getNum() == 0){
            resources.setType(2);
            resources.setNum(0);
        }else{
            resources.setType(1);
        }

        //查询责任区
        Long userId = SecurityUtils.getCurrentUserId();
        UserDto user = userService.findById(userId);

        if(null == user.getAreaId()){
            throw new BadRequestException("抱歉，无法匹配责任区");
        }
        resources.setAreaId(user.getAreaId());
        //处理结束日期以59：59：59结束
        if(null != resources.getEndTime()){
            resources.setEndTime(DateUtils.longToTimeStamp(DateUtils.getDailyEndTime(resources.getEndTime().getTime())));
        }
        AppWorkConfig save = appWorkConfigRepository.save(resources);
        //如果日期是当天，则生成任务
        if(resources.getStartTime().getTime() == DateUtils.getDayStartTimelong()){
            System.out.println("----------执行当前任务----------");
            actWorkConfig(resources.getConfigId());
        }

        return appWorkConfigMapper.toDto(save);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(AppWorkConfig resources) {
        AppWorkConfig appWorkConfig = appWorkConfigRepository.findById(resources.getConfigId()).orElseGet(AppWorkConfig::new);
        ValidationUtil.isNull( appWorkConfig.getConfigId(),"AppWorkConfig","id",resources.getConfigId());
        appWorkConfig.copy(resources);
        appWorkConfigRepository.save(appWorkConfig);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer configId : ids) {
            appWorkConfigRepository.deleteById(configId);
        }
    }

    @Override
    public void download(List<AppWorkConfigDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AppWorkConfigDto appWorkConfig : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("任务名称", appWorkConfig.getTitle());
            map.put("类型", appWorkConfig.getType());
            map.put("关联责任区ID", appWorkConfig.getAreaId());
            map.put("选择职务类型", appWorkConfig.getZhiwuId());
            map.put("任务类型", appWorkConfig.getLabel());
            map.put("紧急程度", appWorkConfig.getJjcd());
            map.put("内容", appWorkConfig.getNote());
            map.put("地址", appWorkConfig.getAddress());
            map.put("经度", appWorkConfig.getLon());
            map.put("纬度", appWorkConfig.getLat());
            map.put("开始时间", appWorkConfig.getStartTime());
            map.put("结束时间", appWorkConfig.getEndTime());
            map.put("巡护频次", appWorkConfig.getNum());
            map.put("频次单位", appWorkConfig.getDanwei());
            map.put("选择人员ID", appWorkConfig.getUids());
            map.put("状态", appWorkConfig.getStatus());
            map.put(" createTime",  appWorkConfig.getCreateTime());
            map.put(" updateTime",  appWorkConfig.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}